//    Copyright (C) Kherty.  All rights reserved.
using System.Collections.Generic;
using System.Diagnostics.Contracts;

namespace OpenLS.Spreadsheet.Expressions
{
    internal sealed class RangeReferenceExpression : CellEnumeratorExpression
    {
        public override string ToString()
        {
            return RangeReference.Label;
        }
        private readonly Worksheet _caller;
        public readonly RangeReference RangeReference;
        public override IEnumerable<Expression> GetSubExpressions()
        {
            yield break;
        }
        
        public RangeReferenceExpression(RangeReference rangeReference, Worksheet caller)
        {
            Contract.Requires(rangeReference != null);
            _caller = caller;
            RangeReference = rangeReference;
        }

        public RangeReferenceExpression(CellReference topLeft, CellReference bottomRight, Worksheet caller)
            : this(new MultiCellsRangeReference(topLeft, bottomRight), caller)
        {
        }
        internal override Expression Transposed(Cell target)
        {
            return new RangeReferenceExpression(RangeReference.Transposed(target), Caller);
        }

        public override object GetValue(EvaluationContext context)
        {
            bool isArray = context is CellEvaluationContext && ((CellEvaluationContext) context).IsArray;
            if (!isArray)
                return RangeReference.Offset(context.Offset).Range.TopLeftCell.Value;
            return (new RangeReferenceExpressionEvaluator(this, context));
        }

        public override Expression Offset(CellRelativeAddress a)
        {
            return new RangeReferenceExpression(RangeReference.Offset(a), Caller);
        }

        public override Worksheet Worksheet
        {
            get { return RangeReference.Worksheet; }
        }

        public Worksheet Caller
        {
            get { return _caller; }
        }

        public override string GetText(TextContext context)
        {
            string s = "";
            if (Caller != RangeReference.Worksheet)
                s += RangeReference.Worksheet.SafeName + "!";
            return s + RangeReference.Label;
        }

        public override IEnumerable<IDependencyNode> GetPrecedents(EvaluationContext context)
        {
            Range rr = RangeReference.Offset(context.Offset).Range;
            yield return rr.Worksheet.RangeManager.GetNode(rr);
//                new RangeNode(rr);
        }

        protected internal override ICellEnumerator GetCellsValue(EvaluationContext context)
        {
            return RangeReference.Offset(context.Offset).Range;
        }
    }
}